package ru.nnstu.server;

import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * @author Kryukov Ilya (kryukov.i@tecomgroup.ru)
 * @version 1.0 Main server create and loads player's character to server
 */
public class Server implements PlayerService {
	private static int onlinePlayer = 0;
	private static final Logger LOG = Logger.getLogger(Server.class);
	private static final ApplicationContext SRV = new ClassPathXmlApplicationContext(
			new String[] { "classpath:ru/nnstu/server/serverContext.xml",
					"classpath:ru/nnstu/server/jmsContext.xml" });

	private HibernateTemplate hibernateTemplate;

	public void setSessionFactory(final SessionFactory sessionFactory) {
		this.hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

	public boolean createPlayer(String name, String sex) {
		PlayerImpl tmpPlayer = (PlayerImpl) SRV.getBean("Player");
		tmpPlayer.setName(name);
		tmpPlayer.setSex(sex);
		// add to db
		insertPlayer(tmpPlayer);
		// add to container
		++onlinePlayer;
		return true;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void insertPlayer(final PlayerImpl player)
			throws DataAccessException {
		this.hibernateTemplate.save(player);
		TopicPublisher ep = (TopicPublisher) SRV.getBean("topicPublisher");
		ep.produce1(player);
	}

	private void init() {
		LOG.info("Initialization start...");

		LOG.info("Initialization finish!");
	}

	public Server() {
		init();
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
	public ArrayList<PlayerImpl> getPlayersByName(String name) {
		return (ArrayList<PlayerImpl>) hibernateTemplate.find(
				"from PlayerImpl player where player.name=?", name);
	}

	@Override
	public boolean createPlayer(PlayerImpl player) {
		++onlinePlayer;
		insertPlayer(player);
		return true;
	}

	@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
	public boolean isContaints(PlayerImpl player) {
		return !(hibernateTemplate.findByExample(player).isEmpty());
	}

	public static long getOnlinePlayer() {
		return onlinePlayer;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ArrayList<PlayerImpl> getAllPlayerImpls() {
		return (ArrayList<PlayerImpl>) hibernateTemplate
				.find("from PlayerImpl player");
	}
}
